package nl.liacs.swi.tower;

import java.util.List;


/*
 * Ant class.
 * 
 * An ant holds a position P(x,y) and goes into a direction D.
 * It holds a copy of the world map, in which it saves the visited
 * cells. The ants automatically find their way on the road using
 * the followPath() method.  If an ant reaches the end of the map or 
 * dies, it is stored as finished (boolean isFinished)
 * 
 */
public class Ant {
	
	private Game game;
	
	private int x;
	private int y;
	private int direction;
	private int map[][];
	private boolean isFinished;
	private boolean isDead;

	final int GO_DOWN = 1;
	final int GO_UP = 2;
	final int GO_LEFT = 3;
	final int GO_RIGHT = 4;

	int SPEED = 5;
	
	// default life is 10
	int life = 50;
	int range = 40;
	int firePower = 0;
	private int RELOAD_TIME = 50;
	private int tick = 0;

	/*
	 * Constructor of ant.
	 * 
	 * Ants holds a copy of the world matrix, which it uses to navigate through
	 * the world.
	 */
	public Ant(Game game) {
		this.game = game;
		// Make an internal copy of the world map
		map = Map.getSingletonObject().getMapCopy();
	}
	
	public Ant(Game game,int life){
		this.game = game;
		this.life = life;
		map = Map.getSingletonObject().getMapCopy();
	}

	public int getX() {
		return x;
	}

	public int getY() {
		return y;
	}

	public void setX(int aX) {
		this.x = aX;
	}

	public void setY(int aY) {
		this.y = aY;
	}

	public boolean isFinished() {
		return this.isFinished;
	}

	private void setFinished() {
		this.game.incFinished();
		this.isFinished = true;
	}

	public boolean isDead() {
		return isDead;
	}

	private void setDead(boolean isDead) {
		this.game.incKills();
		this.isDead = isDead;
	}

	public void update(List<Tower> towers) {
		if(!isDead && !isFinished){
			followPath();
			tick++;
			if (tick == RELOAD_TIME) {
				this.hitsTowers(towers);
				
			}
			if (tick > RELOAD_TIME) {
				tick = 0;
			}
		}
	}
	
	public void hitsTowers(List<Tower> towers) {
		for (Tower tower : towers) {
			if (!tower.isDead() && this.canHit(tower)) {
				tower.getsShot(firePower);
				break;
			}
		}
	}
	
	public boolean canHit(Tower tower) {
		if ((tower.getX() > this.x - range) && (tower.getX() < this.x + range) && (tower.getY() < this.y + range)
				&& (tower.getY() < this.y + range)) {
			return true;
		}
		return false;
	}

	/*
	 * followPath()
	 * 
	 * Code to navigate through the world matrix. An ant always has one, and
	 * only one, direction (up,down,left or right). To avoid the ant going back
	 * in its path, each visited cell in the copy of the world matrix is marked
	 * as visited.
	 */
	private void followPath() {
		int y = (this.y) / 40;
		int x = (this.x) / 40;

		//System.out.println("ANT: x=" + x + " y=" + y + " finished " + this.isFinished);

		// Sprite size = 40
		// Sprite number 
		
		// Check if ant is exactly in the middle of a sprite.
		boolean inMiddle = false;
		for (int i = 0; i < Map.WIDTH; i++)
		{
			for (int j = 0; j < Map.HEIGHT; j++)
			{
				if ( i >= x &&  (this.x > (40*i+10)) && (this.x < (40*i+30)) ) 
				{
					if (j >= y && (this.y > (40*j+10) && (this.y < (40*j+30))))
					{
					inMiddle = true;
					break;
					}
				}
			}
			
		}
			
		if (inMiddle)
		{
			if (y < Map.HEIGHT - 1 && (map[y + 1][x] == 1 || map[y + 1][x] == 2))
				direction = GO_DOWN;
			if (y > 0 && (map[y - 1][x] == 1 || map[y - 1][x] == 2))
				direction = GO_UP;
			if (x < Map.WIDTH - 1 && (map[y][x + 1] == 1 || map[y][x + 1] == 2))
				direction = GO_RIGHT;
			if (x > 0 && (map[y][x - 1] == 1 || map[y][x - 1] == 2))
				direction = GO_LEFT;

		}
		

		
		/*
		if (y < Map.HEIGHT - 1 && map[y + 1][x] == 1)
			direction = GO_DOWN;
		if (y > 0 && map[y - 1][x] == 1)
			direction = GO_UP;
		if (x < Map.WIDTH - 1 && map[y][x + 1] == 1)
			direction = GO_RIGHT;
		if (x > 0 && map[y][x - 1] == 1)
			direction = GO_LEFT;
*/

		// check if is at the end
		if ((y < Map.HEIGHT - 1 && map[y ][x] == 2)
				|| (y > 0 && map[y][x] == 2)
				|| (x < Map.WIDTH - 1 && map[y][x] == 2)
				|| (x > 0 && map[y][x] == 2))
			this.setFinished();

		// Move into direction
		if (!this.isFinished) {
			map[y][x] = 3;
			if (this.direction == GO_RIGHT)
				this.x += SPEED;
			else if (this.direction == GO_DOWN)
				this.y += SPEED;
			else if (this.direction == GO_UP)
				this.y -= SPEED;
			else if (this.direction == GO_LEFT)
				this.x -= SPEED;
		}
	}

	
	/**
	 * this method gets called from the tower if he shots at ant
	 */
	public void getsShot(int firePower){
		life = life - firePower;
		if(life <= 0){
			this.setDead(true);
		}
	}
}
